<template>
	<el-select ref="mySel" :size="size" v-model="val" @change="change" 
		:placeholder="placeholder" 
		:multiple="multiple" 
		:clearable="clearable"
		@visible-change="visibleChange"
	>
		<el-option v-for="item in data" :key="item[defaultProps.id]" :label="item[defaultProps.label]" :value="item[defaultProps.id]" v-show="false"></el-option>
		<el-option :value="mineStatus" style="height: auto;">
			<el-tree ref="tree" 
				:data="treedata" 
				accordion show-checkbox check-strictly highlight-current 
				:node-key="defaultProps.id" 
				:expand-on-click-node="false" 
				:default-checked-keys="ids" 
				:default-expanded-keys="ids"
				check-on-click-node 
				:props="defaultProps"  
				@check-change="handleCheckChange"
			></el-tree>
		</el-option>
	</el-select>
</template>

<script>
	export default {
		name: 'comboTree',
		props: {
			value: {
				type:String | Number | Array
			},
			clearable:{
				type:Boolean,
				default:false
			},
			treeData: Array,
			url: {
				type:String,
			},
			placeholder: {
				type: String,
				default: '请选择'
			},
			multiple: {
				type: Boolean,
				default: false
			},
			nodeKey: {
				type: String,
				default: 'id'
			},
			props: {
				type: Object,
				default() {
					return {
						children: 'children',
						label: 'name',
						id: 'id',
						pid:'parentId',
						// disabled:function(data,node){
						// 	return !node.isLeaf;
						// }
					};
				}
			},
			size:{
				type: String,
				default:'small'
			},
		},
		data() {
			return {
				data: [],
				treedata:[],
				ids:[],
				mineStatus:'',
				nodeChanged:false,
				props2: {
					children: 'children',
					label: 'name',
					id: 'id',
					pid:'parentId',
				}
			}
		},
		computed:{
			defaultProps(){
				return Object.assign({},this.props2,this.props);
			},
			val: {
				get() {
					return this.value;
				},
				set(val) {
				  //改变由父组件控制
				  this.$emit("input", val);
				}
			}
		},
		methods:{
			change(val){
				if(this.multiple){
					let nodes=[];
					for(var i=0;i<val.length;i++){
						for(var j=0;j<this.data.length;j++){
							var obj=this.data[j];
							if(obj[this.defaultProps.id]==val[i]){
								nodes.push(obj);
								break;
							}
						}
					}
					this.$refs.tree.setCheckedNodes(nodes);
				}else {
					if(!val){
						this.$refs.tree.setCheckedKeys([])
					}
				}
				this.$emit("change",val);
			},
			visibleChange(flag){
				if(flag){
					if(this.value){
						if(this.multiple){
							this.ids=this.value;
						}else{
							this.ids=[this.value];
						}
						this.$refs.tree.setCheckedKeys(this.ids);
					}else{
						this.$refs.tree.setCheckedKeys([]);
					}
				}
			},	
			handleCheckChange(data, checked, node) {
				let old=this.value;
				let nodes=this.$refs.tree.getCheckedKeys(false);
				if(this.multiple){
					//this.value=nodes;
					this.$emit('input',nodes);
					// this.$refs.mySel.blur();
				}else{
					if(checked){
						this.$refs.tree.setCheckedKeys([data[this.defaultProps.id]],false);
						// this.value=data[this.defaultProps.id];
						this.nodeChanged=true;
						this.$emit('input',data[this.defaultProps.id]);
						this.$refs.mySel.blur();
					}else{
						setTimeout(()=>{
							if(!this.nodeChanged){
								this.$emit('input',[]);
							}
							this.nodeChanged=false;
						},5);
					}
				}
			},
			// 将树型数据转换为扁平数组
			treeToList (tree) {
				var queen = [];
				var out = [];
				queen = queen.concat(tree);
				while (queen.length) {
					var first = queen.shift();
					var obj=Object.assign({},first);
					obj[this.defaultProps.children]=[];
					if (first[this.defaultProps.children]&&first[this.defaultProps.children].length) {
						queen = queen.concat(first[this.defaultProps.children]);
					}
					out.push(obj);
				}
				return out;
			},
			 // 将一维的扁平数组转换为多层级对象
			buildTree(data, id) {
				const fa = (id) => {
					const temp = [];
					for (let i = 0; i < data.length; i++) {
						const n = data[i];
						if (n[this.defaultProps.pid]=== id) {
							n[this.defaultProps.children] = fa(n[this.defaultProps.id]);
							temp.push(n);
						}
					}
					return temp;
				};
				return fa(id);
			},
			
		},
		created() {
			if(this.treeData){
				this.treedata=this.treeData;
				this.data=this.treeToList(this.treeData);
				if(this.multiple){
					this.ids=this.value;
				}else{
					this.ids=[this.value];
				}
			}else {
				this.$ajax.post(this.url,{}).then(res=>{
					this.data=res.data.data;
					this.treedata=this.buildTree(this.data);
					if(this.multiple){
						this.ids=this.value;
					}else{
						this.ids=[this.value];
					}
				})
			}
		},
		mounted() {
			
		},
		watch: {
			treeData(newValue, oldValue) {
				if(!this.url){
					this.treedata=newValue;
					this.data=this.treeToList(this.treedata);
					if(this.multiple){
						this.$refs.tree.setCheckedKeys(this.val);
					}else{
						this.$refs.tree.setCheckedKeys([this.val]);
					}
				}
			},
		},
	}
</script>

<style scoped>
	.el-select-dropdown__item.hover, .el-select-dropdown__item:hover{
		background-color: #fff;
	}
</style>
